package com.kingbook.api.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.kingbook.common.constant.Status;
import com.kingbook.common.thread.Threads;
import com.kingbook.common.utils.ExeclUitl;
import com.kingbook.common.utils.NumberUtils;
import com.kingbook.common.utils.OSUtils;
import com.kingbook.core.annotations.ContainProperties;
import com.kingbook.core.auth.LoginManager;
import com.kingbook.core.result.JSONPageResult;
import com.kingbook.core.result.JSONResult;
import com.kingbook.entity.Device;
import com.kingbook.entity.Version;
import com.kingbook.services.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.kingbook.core.auth.LoginManager.AUTH;
import static com.kingbook.core.auth.LoginManager.SIGN;
import static org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER;
import static org.apache.poi.ss.usermodel.HorizontalAlignment.LEFT;

/**
 * @Author Bucky
 * @Date 2019-11-05 22:56:45
 * @Version 1.0
 */
@Slf4j
@RestController
public class AppActionRest {

    @Autowired
    DeviceService deviceService;

    @Autowired
    MasterService masterService;

    @Autowired
    WorkorderService workorderService;

    @Autowired
    VersionService versionService;

    @Value("${version}")
    String version;

    /**
     * 设备信息注册,APP第一次打开时注册sign，能统计APP打开量
     *
     * @param param
     * @return
     */
    @PostMapping("genSign")
    @ContainProperties({"appId", "appVersion", "appVersionCode", "imei", "brand", "model", "platform"})
    public JSONResult genSign(@RequestBody Map<String, Object> param) {
        log.info("---->{}", param);
        try {
            // 改成用唯一码生成
            String sign = NumberUtils.uuid16();
            param.put("sign", sign);
            deviceService.save(param);
            JSONObject json = new JSONObject();
            json.put("sign", sign);
            return JSONResult.success(json);
        } catch (Exception e) {
            return JSONResult.failed("签名失败");
        }
    }

    /**
     * 发送验证码
     *
     * @param param
     * @return
     */
    @PostMapping("sendVcode")
    @ContainProperties({"phoneNo"})
    public JSONResult sendVcode(@RequestBody Map<String, Object> param, @RequestHeader(name = SIGN) String sign) {
        log.info("---->{}", param);
        try {
            return masterService.sendVcode(param, sign);
        } catch (Exception e) {
            return JSONResult.failed("发送验证码失败");
        }
    }


    /**
     * 用户登录，第一次登录自动创建用户，后续登录修改登录次数
     *
     * @param param
     * @return
     */
    @PostMapping("doLoginPhone")
    @ContainProperties({"phoneNo", "vCode"})
    public JSONResult doLoginPhone(@RequestBody Map<String, Object> param, @RequestHeader(name = SIGN) String sign) {
        log.info("---->{}", param);
        try {
            return masterService.doLoginPhone(param, sign);
        } catch (Exception e) {
            log.error("---->使用手机号登录失败.");
            return JSONResult.failed("使用手机号登录失败");
        }
    }

    /**
     * 用户登录，第一次登录自动创建用户，后续登录修改登录次数
     *
     * @param param
     * @return
     */
    @PostMapping("doLoginWx")
    @ContainProperties({"openId", "unionId", "nickName", "avatarUrl", "sign"})
    public JSONResult doLoginWx(@RequestBody Map<String, Object> param) {
        log.info("---->{}", param);
        try {
            return masterService.doLoginWx(param);
        } catch (Exception e) {
            log.error("---->使用微信登录失败.");
            return JSONResult.failed("使用微信登录失败");
        }
    }

    @PostMapping("checkAndUpdate")
    @ContainProperties({"appId", "appVersion", "appVersionCode"})
    public JSONResult checkAndUpdate(@RequestBody Map<String, Object> param, @RequestHeader(name = SIGN) String sign) {
        log.info("---->sign={}  {}", sign, param);
//        Device device = deviceService.queryDeviceBySign(sign);
//        if (device == null) {
//            log.info("---->签名不合法 sign:{} ", sign);
//            return JSONResult.failed("签名不合法");
//        }
        Version version = versionService.getLastVersion();
        int appVersionCode = MapUtils.getIntValue(param, "appVersionCode");
        JSONObject json = new JSONObject();
        json.put("released", "no");
        if (version.getVersionCode() > appVersionCode && appVersionCode > 99) {     //防止取不到该参数，默认为0
            json.put("released", version.getReleased());
            json.put("content", version.getContent());
            json.put("url", version.getUrl());
            Threads.asyncExecute(() -> {
                param.put(SIGN, sign);
                deviceService.modify(param);                        //更新设备APP版本
                versionService.addUpgradeTimes(version.getId());    //增加版本下载次数
            });
        }
        log.info("-->新版本:{}", json);
        return JSONResult.success(json);
    }

    @GetMapping("view/{id}")
    public JSONResult view(@PathVariable String id) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("mid", 2000);
        return workorderService.query(param);
    }

    @GetMapping("export")
    public void export(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader("Content-Disposition", "attachment;filename=" + new String("台班单明细.xls".getBytes(), "iso-8859-1"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        OutputStream out = response.getOutputStream();
        ExeclUitl execlUitl = new ExeclUitl();
        String label = "台账明细表";
        List<ExeclUitl.ExeclTitle> titles = Lists.newArrayList();
        titles.add(execlUitl.createExeclTitle("seq", "序号", 5, CENTER));
        titles.add(execlUitl.createExeclTitle("workDate", "日期", 11, CENTER));
        titles.add(execlUitl.createExeclTitle("plateNo", "车辆", 10, CENTER));
        titles.add(execlUitl.createExeclTitle("tons", "吨位", 7, CENTER));
        titles.add(execlUitl.createExeclTitle("chargeNum", "台班", 7, CENTER));
        titles.add(execlUitl.createExeclTitle("duration", "时长", 7, CENTER));
        titles.add(execlUitl.createExeclTitle("amount", "金额", 8, CENTER));
        titles.add(execlUitl.createExeclTitle("address", "地点", 21, LEFT));
        titles.add(execlUitl.createExeclTitle("task", "内容", 21, LEFT));
        Map<String, Object> param = Maps.newHashMap();
        param.put("mid", 2000);
        JSONResult result = workorderService.query(param);
        execlUitl.writeExecls(label, titles, result.getData()).write(out);
        out.close();
    }

    @GetMapping("info")
    public void info(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("session: " + request.getSession(true).getId());
        response.getWriter().write("version: " + version);
        long total = (Runtime.getRuntime().totalMemory()) / (1024 * 1024);
        long max = (Runtime.getRuntime().maxMemory()) / (1024 * 1024);
        long free = (Runtime.getRuntime().freeMemory()) / (1024 * 1024);
        String ss = "<br><br><br><br><br><br>"
                + "<table border=\"1\" bordercolor=\"#FFFFFF\"  bgcolor=\"#EEEEEE\" width=\"80%\" align=\"center\">"
                + "<tr><td width=\"80%\" colspan=\"3\" align=\"center\"><b>Java 虚拟机内存量使用统计</b></td></tr>"
                + "<tr><td width=\"16%\">JVM最大可用内存</td><td width=\"18%\">" + max + "MB</td><td width=\"66%\">Java 虚拟机试图使用的最大内存量  maxMemory</td></tr>"
                + "<tr>	<td>JVM占用内存总数</td><td>" + total + "MB</td><td>Java 虚拟机中的内存总量  totalMemory</td></tr>"
                + "<tr><td>JVM空闲内存</td><td>" + free + "MB</td><td>Java 虚拟机中的空闲内存量  freeMemory</td></tr>"
                + "<tr><td>JVM实际可用内存</td><td>" + (max - total + free) + "MB</td><td>JVM实际可用内存并不等于freeMemory()，而应该等于 maxMemory() - totalMemory() + freeMemory()</td></tr>"
                + "</table>";
        response.getWriter().println(ss);
    }

    @GetMapping("os")
    public void getSystemInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("session: " + request.getSession(true).getId());
        response.getWriter().write("version: " + version);
        String ss = JSON.toJSONString(OSUtils.getSystemInfo());
        response.getWriter().println(ss);
    }
}
